<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>状态模式</title>
	</head>
	<body>
		<script>
			// 状态模式和策略模式的区别:最重要的点就是策略模式的行为函数是独立的(纯的),状态模式的行为函数会用到对象实例的状态。
			// 使用状态模式前, if else 模式
			class CoffeeMaker {
			  constructor() {
			    /**
			    这里略去咖啡机中与咖啡状态切换无关的一些初始化逻辑
			  **/
			    // 初始化状态，没有切换任何咖啡模式
			    this.state = 'init';
			  }
			
			  // 关注咖啡机状态切换函数
			  changeState(state) {
			    // 记录当前状态
			    this.state = state;
			    if(state === 'american') {
			      // 这里用 console 代指咖啡制作流程的业务逻辑
			      console.log('我只吐黑咖啡');
			    } else if(state === 'latte') {
			      console.log(`给黑咖啡加点奶`);
			    } else if(state === 'vanillaLatte') {
			      console.log('黑咖啡加点奶再加香草糖浆');
			    } else if(state === 'mocha') {
			      console.log('黑咖啡加点奶再加点巧克力');
			    }
			  }
			}
			const mk = new CoffeeMaker();
			mk.changeState('latte'); // 输出 '给黑咖啡加点奶'
			// 使用状态模式后
			class CoffeeMaker {
			  constructor() {
			    /**
			    这里略去咖啡机中与咖啡状态切换无关的一些初始化逻辑
			  **/
			    // 初始化状态，没有切换任何咖啡模式
			    this.state = 'init';
			    // 初始化牛奶的存储量
			    this.leftMilk = '500ml';
			  }
			  stateToProcessor = {
			    that: this,
			    american() {
			      // 尝试在行为函数里拿到咖啡机实例的信息并输出
			      console.log('咖啡机现在的牛奶存储量是:', this.that.leftMilk)
			      console.log('我只吐黑咖啡');
			    },
			    latte() {
			      this.american()
			      console.log('加点奶');
			    },
			    vanillaLatte() {
			      this.latte();
			      console.log('再加香草糖浆');
			    },
			    mocha() {
			      this.latte();
			      console.log('再加巧克力');
			    }
			  }
			
			  // 关注咖啡机状态切换函数
			  changeState(state) {
			    this.state = state;
			    if (!this.stateToProcessor[state]) {
			      return;
			    }
			    this.stateToProcessor[state]();
			  }
			}
			
			const mk = new CoffeeMaker();
			mk.changeState('latte');
		</script>
	</body>
</html>
